package org.itydl.game.model

import org.itheima.kotlin.game.core.Painter
import org.itydl.game.Config
import org.itydl.game.business.Attackable
import org.itydl.game.business.AutoMovable
import org.itydl.game.business.Destoryable
import org.itydl.game.business.Sufferable
import org.itydl.game.enums.Direction
import org.itydl.game.ext.checCollection

/**
 * 子弹
 */
// 子弹位置跟坦克有关系，x,y是跟其变化的
// create: (bulletWidth: Int, bulletHeight: Int) -> Pair<Int, Int>调用方应该实现一个闭包函数，入参两个值，返回值类型为Pair<Int, Int>
// 接收一个参数为creat的函数,函数作用是帮助Bullet计算出Bullet的x和y值。 入参两个int子弹宽高，子弹宽高根据子弹图片来计算得到，返回值Pair类型，Pair存储当前子弹的坐标
// A模块调用B模块同时带有参数，B模块依托于前面A模块调用时机的参数；而A模块中的调用参数是变量，又需要依托B模块的某些属性来计算得到，此时考虑使用闭包。
class Bullet(override val from: View, override val currentDirection: Direction, create: (bulletWidth: Int, bulletHeight: Int) -> Pair<Int, Int>) :
        AutoMovable, Destoryable, Attackable, Sufferable { //也具备被击打能力，这样可以把子弹抵消

    override var x: Int = 0
    override var y: Int = 0
    override val width: Int
    override val height: Int

    /**
     * 子弹移动速度
     */
    override val speed: Int = 8

    /**
     * 子弹该攻击者的攻击能力默认值
     */
    override val power: Int = 1

    /**
     * 是否具备销毁能力
     */
    private var isDestory: Boolean = false

    override val blood: Int = 1

    // 根据方向确定当前方向上的子弹
    private val shotImagePath = when (currentDirection) {
        Direction.UP -> "img/shot_top.gif"
        Direction.DOWN -> "img/shot_bottom.gif"
        Direction.LEFT -> "img/shot_left.gif"
        Direction.RIGHT -> "img/shot_right.gif"
    }

    init {
        // 根据图片计算当前子弹的宽高
        val size: Array<Int> = Painter.size(shotImagePath)
        width = size[0]
        height = size[1]

        // 调用坦克中的闭包方法，返回值是已经创建好的子弹的坐标封装
        // 调用坦克里面的方法，入参：当前子弹的宽高，返回值当前子弹的实际x,y坐标
        val pair: Pair<Int, Int> = create.invoke(width, height)
        // 调用闭包函数，返回值是该子弹的坐标
        x = pair.first
        y = pair.second
    }

    /**
     * 子弹的移动
     * 根据自己的方向做对应的移动
     */
    override fun autoMove() {
        when (currentDirection) {
            Direction.UP -> y -= speed
            Direction.DOWN -> y += speed
            Direction.LEFT -> x -= speed
            Direction.RIGHT -> x += speed
        }
    }

    /**
     * 绘制子弹
     */
    override fun draw() {
        Painter.drawImage(shotImagePath, x, y)
    }

    /**
     * 子弹具备销毁能力
     * 在什么时候可以销毁
     */
    override fun isDestory(): Boolean {
        // 2、找到被攻击者（跟被攻击者发生碰撞），销毁自己
        if (isDestory) {
            return true
        }

        // 检测子弹何时应该被销毁
        // 1、超出屏幕后（回收）
        return when {
            x < -width -> true
            x > Config.gameWidth -> true
            y < -height -> true
            y > Config.gameHeight -> true
            else -> false
        }
    }

    /**
     * 检测子弹跟具备遭受攻击的物体是否发生"接触"
     */
    override fun isCollection(sufferable: Sufferable): Boolean {
        // 检测碰撞的逻辑
        return checCollection(sufferable)
    }

    /**
     * 通知找到被攻击者，子弹做回收工作
     */
    override fun notifyAttached(sufferable: Sufferable) {
        isDestory = true
    }

    /**
     * 遭受击打，放出火花
     */
    override fun notifySuffered(attackable: Attackable): Array<View>? {
        return arrayOf(Blast(x, y))
    }
}